package main
import (
	"fmt"
)
//类型断言的最佳实践1！
//：前面接口5例子中，当Phone结构体有个特有的方法call()时，USB接口接收的是Phone变量时，还需要调用call()方法
func main(){
	var usbArr [3]USB
	usbArr[0] = Phone{"小米"}
	usbArr[1] = Phone{"vivo"}
	usbArr[2] = Camera{"尼康"}
	fmt.Println("UsbArr: ",usbArr)
	//遍历usbArr
	var c Computer
	for _,value := range usbArr{
		c.Working(value)
	}
}

type USB interface{ //接口的定义
	Start()		//接口的两个方法！
	Stop()
}

type Phone struct{
	name string
}
//让该结构体Phone实现接口的方法
func (p Phone) Start(){
	fmt.Println("手机开始工作...")
}
func (p Phone) Stop(){
	fmt.Println("手机停止工作...")
}
func (p Phone) Call(){ //Phone 结构体特有方法！
	fmt.Println("手机开始打电话...")
}
type Camera struct{
	name string
}
//让该结构体Camera实现接口的方法
func (c Camera) Start(){
	fmt.Println("相机开始工作...")
}
func (c Camera) Stop(){
	fmt.Println("相机停止工作...")
}

//计算机
type Computer struct{

}
//编写一个方法，可以接收USB接口类型的的参数
//只要实现了USB接口的方法，“也就是说实现了USB接口声明的【所有】方法”
func (c Computer)Working(usb USB){    //体现出了多态
	//通过接口变量来调用Start和Stop接口的方法
	usb.Start()
	usb.Stop()
	//如果usb是一个Phone时，需要在调用call方法！
	//类型断言............................................................................................................
	if phone,ok := usb.(Phone);ok{ //通过if来判断该参数是不是指向Phone，是就执行call不是就跳过！
		phone.Call()
	}
	//类型断言............................................................................................................
}